<template>
  <div>
    <chessboard :free="ifFree" :orientation="boardColor" @onMove="getInfo" :onPromotion="promote"
                :fen="currentFen"/>
  </div>
</template>

<script>
// 国际象棋棋盘逻辑和操作组件
import {chessboard} from 'vue-chessboard';
import 'vue-chessboard/dist/vue-chessboard.css';
import bus from 'emitvue';
import * as utils from "./utils";
import * as  tcp from './tcp.js';
import {clipboard} from "electron";


export default {
  name: "chess",
  data() {
    return {
      ifFree: false,//随意走子
      boardColor: 'white',//棋盘朝向
      currentFen: '',//utils.newGame, // 默认的fen
      stepFen: null,
      // 棋谱
      fgnList: [], //结构 fgn,fen
      boardData: null,//棋盘信息
      newGameModal: false,
      // 目前的fgn
      currentFgn: [],
      // 是否忽略这次的局面改动
      ignore: false,
      history: [],
      autoAnalyze: false,
    }
  },
  methods: {
    // 每次移动棋子会触发
    async getInfo(data) {
      bus.$emit('enabledSave', null);
      console.log("目前棋盘信息 ->", data);
      this.boardData = data;
      this.currentFgn = data.history;

      this.stepFen = data.fen;
      this.showFgnList();
      // 保存历史
      this.fgnList.push({
        fen: data.fen,
        fgn: data.history
      })

      let last = utils.getLastNext(this.fgnList);
      if (!last) {
        last = {};
      }
      let fen = utils.getLastNext(this.fgnList).fen;

      let first = this.fgnList[1] ? this.fgnList[1].fgn[0] : null;
      if (!fen || !first) {
        // 初始局面不需要向引擎获取信息
        return;
      }
      // 每次下棋处理历史信息
      if (this.currentFgn.length) {
        this.history.push(this.currentFgn[this.currentFgn.length - 1])
      }

      let fen_step = data.history[data.history.length - 1];
      if (!fen_step) {
        return;
      }
      let sendMsg = {
        operator: 'get_fen_name',
        data: {
          fen, first,
          step: data.history[data.history.length - 1],
        }
      }
      try {
        let res = await tcp.send(sendMsg, utils.ip, utils.port);
        console.log("获取开局名结果为 res->", res);
        let data = res.data;
        bus.$emit('updateFenName', data);

      } catch (error) {
        console.log('获取开局名称出错 e->', error);
      }
      if (this.autoAnalyze) {
        await this.analyze(data.fen);
      }
      this.$forceUpdate()

    },
    // 升变
    promote() {
      //q:Queen, r:Rook, k:Knight, b:Bishop
      // 后期结合上对话框 先写死升变皇后
      return 'q';
    },
    updateScore(score) {
      bus.$emit('updateScore', score);
    },
    showFgnList() {
      bus.$emit('showFgnList', this.history);
    },
    // 保存局面
    async saveFgn(data) {
      // 保存局面 是取上一步的fgn 以及这一步的走法
      let {name, nameEn} = data;
      let step = utils.getLast(utils.getLast(this.fgnList).fgn);
      // 防止数据库单引号报错
      name = name.replace(`'`, `''`)
      nameEn = nameEn.replace(`'`, `''`)
      let sendData = {
        operator: 'save_fen',
        data: {
          name,
          nameEn,
          fen: utils.getLastNext(this.fgnList).fen || utils.newGame,
          step,
          // 告诉引擎第一步棋是什么 决定存到哪个数据库里面e4 d4 other
          first: this.fgnList[1].fgn[0],
        }
      }
      if (step === '') {
        this.$Message.error("初始局面不能保存");
        return;
      }
      let res = await tcp.send(sendData, utils.ip, utils.port);
      console.log("保存棋谱的结果为 ", res);
      if (res.code === 0) {
        this.$Message.success(res.message || '成功');

      } else {
        this.$Message.warning(res.message || '存在问题');
      }
    },
    // 棋盘前进后退操作
    back() {

    },
    step() {

    },
    async analyze(fen) {
      try {
        bus.$emit('updateAnalyzeLoading', true);
        let sendMsg = {
          operator: 'analyze',
          data: {
            fen
          }
        }
        let result = await tcp.send(sendMsg, utils.ip, utils.port);
        console.log("目前的历史信息为 ", this.fgnList);
        console.log("引擎分析结果为 ", result);
        if (result.code !== 0 ) {
          this.$Message.info('棋局结束，原因为:' + result.message);
        }
        console.log("fen->", result.data.fen);
        let {step, uci, score} = result.data;
        let updateAnalyzeList = [];
        updateAnalyzeList.push({
          step,
          score,
          last: '暂无'
        })
        bus.$emit('updateAnalyze', updateAnalyzeList)
        // 更新评分
        this.updateScore(score)
        // 手动维护历史信息
        this.history.push(step);
        this.currentFen = result.data.fen;
        console.log("重新设置fen为->", this.currentFen);
        bus.$emit('updateAnalyzeLoading', false);
        this.$forceUpdate();
      } catch (err) {
        console.log("引擎分析报错->", err)
        bus.$emit('updateAnalyzeLoading', false);
        this.$forceUpdate();
      }

    }
  },
  async mounted() {
    bus.$on("newGame", async () => {
      // 20211127 暂时先整个页面重新刷新 后续看怎么优化
      location.reload();
    });
    bus.$on('saveFgn', async (value) => {
      console.log("收到保存棋谱的请求 ，value->", value);
      await this.saveFgn(value);
    });
    // 前进 后退按钮
    bus.$on('back', () => {
      this.back();
    });
    bus.$on('step', () => {
      this.step();
    });
    bus.$on('switchAnalyze', (value) => {
      this.autoAnalyze = value;
      console.log("切换自动分析 ", this.autoAnalyze);
      let text = this.autoAnalyze === true ? '开始自动分析' : '关闭自动分析';
      this.$Message.info(text);
    })
    //手动分析
    bus.$on('analyze', () => {
      console.log("this.history", this.fgnList);
      let fen = this.fgnList.length > 0 ? this.fgnList[this.fgnList.length - 1].fen : utils.newGame;
      this.analyze(fen);
    })
    // 获取fen并黏贴至剪贴板
    bus.$on('getFen2Clipboard', () => {
      let fen = this.fgnList.length > 0 ? this.fgnList[this.fgnList.length - 1].fen : utils.newGame;
      clipboard.writeText(fen)
      this.$Message.success('保存到剪贴板成功!')
    })
    // 翻转棋盘
    bus.$on('reverseBoard', () => {
      this.boardColor = this.boardColor === 'white' ? 'black' : 'white';
      this.$Message.info("翻转棋盘");
    })
    // 自由移动好像没啥用
    bus.$on('freeMove', () => {
      this.ifFree = !this.ifFree;
      this.$Message.info(this.ifFree === true ? '开启自由移动' : '关闭自由移动');
    })
  },

  components: {
    chessboard
  }
}
</script>

<style scoped>

</style>
